package com.tmp.alarm.task;

import com.tmp.alarm.utils.MySQLUtils;
import com.tmp.alarm.utils.PropertiesUtil;
import com.tmp.alarm.utils.SendMessagesUtils;
import com.tmp.alarm.utils.UUIDByDateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.ResultSet;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 *根据job来自不同的提交方式与所占总的提交方式比例的大小来告警
 */
public class CountJobAlarm {

    private  final  static Logger LOGGER = LoggerFactory.getLogger(CountJobAlarm.class);

    private  final  static  String processing_type = PropertiesUtil.get("processing_type").trim();
    private  final  static String final_type = PropertiesUtil.get("final_type").trim();

    /**
     * 统计提交的任务的方式,并告警,统计查询type=1的值,并且统计完后将type改为type=2
     * BUFFALO:走正常提交任务流程
     * GATEONE:直接在堡垒机上提交
     * ide_online:直接在bdp界面提交的sql产生的job
     * ide_job:调度任务产生的job
     */
    public static  void countSubJobWaysRateAlarm(){

        String currentTime = UUIDByDateUtils.getCurrentTimes("yyyyMMddHHmmss");

        String allSql = "SELECT count(1)  AS sumnums FROM("+
                "SELECT * FROM mart_mobile_job_info AS m " +
                "WHERE m.type=1 AND m.log_time<="+currentTime+" GROUP BY job_id) AS tmp";

        String BUFFALOSql = "SELECT count(1)  AS sumnums FROM("+
                "SELECT * FROM mart_mobile_job_info AS m " +
                "WHERE m.type=1 AND m.log_time<="+currentTime+" AND m.application_name LIKE '%BUFFALO%' GROUP BY job_id) AS tmp";

        String GATEONESql = "SELECT count(1)  AS sumnums FROM("+
                "SELECT * FROM mart_mobile_job_info AS m " +
                "WHERE m.type=1 AND m.log_time<=" +currentTime+" AND m.application_name LIKE '%GATEONE%' GROUP BY job_id) AS tmp";

        String ide_onlineSql ="SELECT count(1)  AS sumnums FROM("+
                "SELECT * FROM mart_mobile_job_info AS m " +
                "WHERE m.type=1 AND m.log_time<=" +currentTime+" AND m.application_name LIKE '%ide_online%' GROUP BY job_id) AS tmp";

        String ide_jobSql = "SELECT count(1)  AS sumnums FROM("+
                "SELECT * FROM mart_mobile_job_info AS m " +
                "WHERE m.type=1 AND m.log_time<=" +currentTime+" AND m.application_name LIKE '%ide_job%' GROUP BY job_id) AS tmp";


        Connection connection = null;
        String totalJobs="";
        String buffaloJobs = "";
        String gateoneJobs="";
        String ideonlineJobs="";
        String idejobNums="";
        try {
            connection = MySQLUtils.getConnection();
            totalJobs = countJobs(allSql,connection);
            if(Integer.parseInt(totalJobs.trim()) <=0){
                LOGGER.info("本次job来源统计totalJobs查询为0在type=1情况下...");
                return;
            }

            buffaloJobs = countJobs(BUFFALOSql,connection);
            gateoneJobs = countJobs(GATEONESql,connection);
            ideonlineJobs = countJobs(ide_onlineSql,connection);
            idejobNums = countJobs(ide_jobSql,connection);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //更新已经查询过的记录,将type设置为2,供进度查询使用
        String update_sql = "UPDATE mart_mobile_job_info SET type="+processing_type+" WHERE type=1";
        MySQLUtils.executeUpdate(connection,update_sql);

        //表jobs_source_alarm告警类型;1表示buffalo,2表示gateone,3表示ide_online,4表示ide_job

        //buffalo类型
        buffaloAlarm(currentTime,totalJobs,buffaloJobs);

        //gateone类型告警
        gateoneAlarm(currentTime,totalJobs,gateoneJobs);

        //ide_online类型浏览器界面提交的任务超过一定比例后,告警
        ideonlineAlarm(currentTime,totalJobs,ideonlineJobs);

        //ide_job类型
        idejobAlarm(currentTime,totalJobs,idejobNums);

        MySQLUtils.returnConnection(connection);

//        LOGGER.info(allNums+"  "+buffaloNums+"  "+gateoneNums+"  "+ideonlineNums+"  "+idejobNums);
    }

    /**
     * buffalo类型统计告警
     * @param currentTime
     * @param totalJobs
     * @param buffaloJobs
     */
    private static void buffaloAlarm(String currentTime,String totalJobs, String buffaloJobs) {

        int buffalo_jobs_limit = Integer.parseInt(PropertiesUtil.get("buffalo_jobs_limit").trim());
        int total_jobs_limit_buffalo = Integer.parseInt(PropertiesUtil.get("total_jobs_limit_buffalo"));
        if(Integer.parseInt(buffaloJobs.trim())<buffalo_jobs_limit && Integer.parseInt(totalJobs.trim())<total_jobs_limit_buffalo){
            LOGGER.info("buffalo类型的jobs数与总jobs数没有超过配置中数,current_buffaloJobs:"+buffaloJobs+" config_buffaloJobs:"+buffalo_jobs_limit+"  current_totalJobs:"+totalJobs+"  config_totalJobs:"+total_jobs_limit_buffalo);
            return;
        }

        float buffaloRate = Float.parseFloat(buffaloJobs)/Float.parseFloat(totalJobs);
        buffaloRate = buffaloRate*100;
        float buffalo_rate = Float.parseFloat(PropertiesUtil.get("buffalo_rate").trim());
        String alarm_limit_time = PropertiesUtil.get("alarm_limit_time").trim();
        if(buffaloRate>buffalo_rate) {
            //告警的手机号
            String alarm_list = PropertiesUtil.get("alarm_phone_list").trim();
            String alarm_title = "buffalo过高";
            String rate = UUIDByDateUtils.twoPointNumbers(buffaloRate+"");
            String alarm_content = "buffalo的任务数过多,共有:" + buffaloJobs + " 个,总任务数有:" + totalJobs + " 个,所占比例为:" + rate + "%";

            //判断在告警记录表(job_source_alarm)中是否有同类型的job告警过,如果alarm_time到当前时间超过了配置中限制时间alarm_limit_time则告警,
            // 否则不同时满足比例大于指定比例,间隔时间不大于指定时间则不告警
            //表jobs_source_alarm告警类型;1表示buffalo,2表示gateone,3表示ide_online,4表示ide_job
            String sql = "SELECT j.id,j.alarm_time FROM jobs_source_alarm j WHERE j.alarm_type=1 ORDER BY id DESC LIMIT 1";
            Connection connection = null;
            ResultSet rs = null;
            try {
                connection = MySQLUtils.getConnection();
                rs = MySQLUtils.query(connection, sql);
                rs.next();
                int rows = rs.getRow();
                //大于0说明jobs_source_alarm中已经告警过该类型的jobs,则根据alarm_time与当前时间判断是否超过了配置中设置的间隔时间alarm_limit_time,超过则再一次告警
                //超过后告警成功则把新的告警记录保存下来,没超过就不用管了
                String addSql = "INSERT INTO jobs_source_alarm (alarm_type,alarm_time,alarm_limit_time,total_jobs,alarm_jobs,alarm_limit_rate) VALUES(1,'" + currentTime + "','" + alarm_limit_time + "'," + totalJobs + "," + buffaloJobs + "," + buffalo_rate + ")";
                if (rows > 0) {
                    String last_alarm_time = rs.getString("alarm_time");
                    boolean buffaloFlag = jdugeJobTimeOut(currentTime, last_alarm_time, Integer.parseInt(alarm_limit_time.trim()));
                    if (buffaloFlag) {
                        LOGGER.info("buffalo在jobs_source_alarm中有该类型告警记录,本次告警距离上次告警超过了指定间隔时间,将告警:" + alarm_content);
                        String flag = SendMessagesUtils.sendMessagesToPhone(alarm_list,alarm_title,alarm_content);
                        if (flag.equals("1")) {
                            LOGGER.info("buffalo类型再次告警发送短信成功...");
                            MySQLUtils.executeUpdate(connection, addSql);
                        } else {
                            LOGGER.error("buffalo告警发送短信失败!!!");
                        }
                    }
                } else {//该类型的job还没有告警过,直接告警,并保存告警记录
                    String flag = SendMessagesUtils.sendMessagesToPhone(alarm_list,alarm_title,alarm_content);
                    if (flag.equals("1")) {
                        LOGGER.info("buffalo该类型首次告警发送短信成功...");
                        MySQLUtils.executeUpdate(connection, addSql);
                    } else {
                        LOGGER.error("buffalo告警发送短信失败!!!");
                    }
                }
                MySQLUtils.returnConnection(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            LOGGER.info("buffalo本次统计比例没有超过指定的比例...");
        }
    }


    /**
     * gateone类型告警
     * @param currentTime
     * @param totalJobs
     * @param gateoneJobs
     */
    private static void gateoneAlarm(String currentTime,String totalJobs, String gateoneJobs) {

        int gateone_jobs_limit = Integer.parseInt(PropertiesUtil.get("gateone_jobs_limit").trim());
        int total_jobs_limit_gateone = Integer.parseInt(PropertiesUtil.get("total_jobs_limit_gateone"));
        if(Integer.parseInt(gateoneJobs.trim())<gateone_jobs_limit && Integer.parseInt(totalJobs.trim())<total_jobs_limit_gateone){
            LOGGER.info("gateone类型的jobs数与总jobs数没有超过配置中数,current_gateoneJobs:"+gateoneJobs+" config_gateoneJobs:"+gateone_jobs_limit+"  current_totalJobs:"+totalJobs+"  config_totalJobs:"+total_jobs_limit_gateone);
            return;
        }

        float gateoneRate = Float.parseFloat(gateoneJobs)/Float.parseFloat(totalJobs);
        gateoneRate = gateoneRate*100;
        float gateone_rate = Float.parseFloat(PropertiesUtil.get("gateone_rate").trim());
        String alarm_limit_time = PropertiesUtil.get("alarm_limit_time").trim();
        if(gateoneRate>gateone_rate) {
            //告警的手机号
            String alarm_list = PropertiesUtil.get("alarm_phone_list").trim();
            String alarm_title = "gateone过高";
            String rate = UUIDByDateUtils.twoPointNumbers(gateoneRate+"");
            String alarm_content = "gateone的任务数过多,共有:" + gateoneJobs + " 个,总任务数有:" + totalJobs + " 个,所占比例为:" + rate + "%";

            //判断在告警记录表(job_source_alarm)中是否有同类型的job告警过,如果alarm_time到当前时间超过了配置中限制时间alarm_limit_time则告警,
            // 否则不同时满足比例大于指定比例,间隔时间不大于指定时间则不告警
            //表jobs_source_alarm告警类型;1表示buffalo,2表示gateone,3表示ide_online,4表示ide_job
            String sql = "SELECT j.id,j.alarm_time FROM jobs_source_alarm j WHERE j.alarm_type=2 ORDER BY id DESC LIMIT 1";
            Connection connection = null;
            ResultSet rs = null;
            try {
                connection = MySQLUtils.getConnection();
                rs = MySQLUtils.query(connection, sql);
                rs.next();
                int rows = rs.getRow();
                //大于0说明jobs_source_alarm中已经告警过该类型的jobs,则根据alarm_time与当前时间判断是否超过了配置中设置的间隔时间alarm_limit_time,超过则再一次告警
                //超过后告警成功则把新的告警记录保存下来,没超过就不用管了
                String addSql = "INSERT INTO jobs_source_alarm (alarm_type,alarm_time,alarm_limit_time,total_jobs,alarm_jobs,alarm_limit_rate) VALUES(1,'" + currentTime + "','" + alarm_limit_time + "'," + totalJobs + "," + gateoneJobs + "," + gateone_rate + ")";
                if (rows > 0) {
                    String last_alarm_time = rs.getString("alarm_time");
                    boolean gateoneFlag = jdugeJobTimeOut(currentTime, last_alarm_time, Integer.parseInt(alarm_limit_time.trim()));
                    if (gateoneFlag) {
                        LOGGER.info("gateone在jobs_source_alarm中有该类型告警记录,本次告警距离上次告警超过了指定间隔时间,将告警:" + alarm_content);
                        String flag = SendMessagesUtils.sendMessagesToPhone(alarm_list,alarm_title,alarm_content);
                        if (flag.equals("1")) {
                            LOGGER.info("gateone类型再次告警发送短信成功...");
                            MySQLUtils.executeUpdate(connection, addSql);
                        } else {
                            LOGGER.error("gateone告警发送短信失败!!!");
                        }
                    }
                } else {//该类型的job还没有告警过,直接告警,并保存告警记录
                    String flag = SendMessagesUtils.sendMessagesToPhone(alarm_list,alarm_title,alarm_content);
                    if (flag.equals("1")) {
                        LOGGER.info("gateone该类型首次告警发送短信成功...");
                        MySQLUtils.executeUpdate(connection, addSql);
                    } else {
                        LOGGER.error("gateone告警发送短信失败!!!");
                    }
                }
                MySQLUtils.returnConnection(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            LOGGER.info("gateone本次统计比例没有超过指定的比例...");
        }
    }


    /**
     * ide_online 类型的job统计判断告警
     * @param currentTime
     * @param totalJobs
     * @param ideonlineJobs
     */
    private static void ideonlineAlarm(String currentTime,String totalJobs, String ideonlineJobs) {


        int ide_online_jobs_limit = Integer.parseInt(PropertiesUtil.get("ide_online_jobs_limit").trim());
        int total_jobs_limit_ide_online = Integer.parseInt(PropertiesUtil.get("total_jobs_limit_ide_online"));
        if(Integer.parseInt(ideonlineJobs.trim())<ide_online_jobs_limit && Integer.parseInt(totalJobs.trim())<total_jobs_limit_ide_online){
            LOGGER.info("ideonline类型的jobs数与总jobs数没有超过配置中数,current_ideonlineJobs:"+ideonlineJobs+" config_ideonlineJobs:"+ide_online_jobs_limit+"  current_totalJobs:"+totalJobs+"  config_totalJobs:"+total_jobs_limit_ide_online);
            return;
        }

        float ideaolineRate = Float.parseFloat(ideonlineJobs)/Float.parseFloat(totalJobs);
        ideaolineRate = ideaolineRate*100;
        float ide_online_rate = Float.parseFloat(PropertiesUtil.get("ide_online_rate").trim());
        String alarm_limit_time = PropertiesUtil.get("alarm_limit_time").trim();
        if(ideaolineRate>ide_online_rate) {
            //告警的手机号
            String alarm_list = PropertiesUtil.get("alarm_phone_list").trim();
            String alarm_title = "ide_line过高";
            String rate = UUIDByDateUtils.twoPointNumbers(ideaolineRate+"");
            String alarm_content = "ide_online提交的任务数过多,共有:" + ideonlineJobs + " 个,总任务数有:" + totalJobs + " 个,所占比例为:" + rate + "%";

            //判断在告警记录表(job_source_alarm)中是否有同类型的job告警过,如果alarm_time到当前时间超过了配置中限制时间alarm_limit_time则告警,
            // 否则不同时满足比例大于指定比例,间隔时间不大于指定时间则不告警
            //表jobs_source_alarm告警类型;1表示buffalo,2表示gateone,3表示ide_online,4表示ide_job
            String sql = "SELECT j.id,j.alarm_time FROM jobs_source_alarm j WHERE j.alarm_type=3 ORDER BY id DESC LIMIT 1";
            Connection connection = null;
            ResultSet rs = null;
            try {
                connection = MySQLUtils.getConnection();
                rs = MySQLUtils.query(connection,sql);
                rs.next();
                int rows =   rs.getRow();
                //大于0说明jobs_source_alarm中已经告警过该类型的jobs,则根据alarm_time与当前时间判断是否超过了配置中设置的间隔时间alarm_limit_time,超过则再一次告警
                //超过后告警成功则把新的告警记录保存下来,没超过就不用管了
                String addSql = "INSERT INTO jobs_source_alarm (alarm_type,alarm_time,alarm_limit_time,total_jobs,alarm_jobs,alarm_limit_rate) VALUES(3,'" + currentTime + "','" + alarm_limit_time + "'," + totalJobs + "," + ideonlineJobs + "," + ide_online_rate + ")";
                if (rows > 0) {
                    String last_alarm_time = rs.getString("alarm_time");
                    boolean ideolineFlag = jdugeJobTimeOut(currentTime, last_alarm_time, Integer.parseInt(alarm_limit_time.trim()));
                    if (ideolineFlag) {
                        LOGGER.info("在jobs_source_alarm中有该类型告警记录,本次告警距离上次告警超过了指定间隔时间,将告警:" + alarm_content);
                        String flag = SendMessagesUtils.sendMessagesToPhone(alarm_list,alarm_title,alarm_content);
                        if (flag.equals("1")) {
                            LOGGER.info("ide_online类型再次告警发送短信成功...");
                            MySQLUtils.executeUpdate(connection, addSql);
                        } else {
                            LOGGER.error("ide_online告警发送短信失败!!!");
                        }
                    }
                } else {//该类型的job还没有告警过,直接告警,并保存告警记录
                    String flag = SendMessagesUtils.sendMessagesToPhone(alarm_list,alarm_title,alarm_content);
                    if (flag.equals("1")) {
                        LOGGER.info("ide_online该类型首次告警发送短信成功...");
                        MySQLUtils.executeUpdate(connection, addSql);
                    } else {
                        LOGGER.error("ide_online告警发送短信失败!!!");
                    }
                }
                MySQLUtils.returnConnection(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            LOGGER.info("ide_online本次统计比例没有超过指定的比例...");
        }
    }


    private static void idejobAlarm(String currentTime,String totalJobs, String idejobJobs) {

        int ide_job_jobs_limit = Integer.parseInt(PropertiesUtil.get("ide_job_jobs_limit").trim());
        int total_jobs_limit_ide_job = Integer.parseInt(PropertiesUtil.get("total_jobs_limit_ide_job"));
        if(Integer.parseInt(idejobJobs.trim())<ide_job_jobs_limit && Integer.parseInt(totalJobs.trim())<total_jobs_limit_ide_job){
            LOGGER.info("idejob类型的jobs数与总jobs数没有超过配置中数,current_idejobJobs:"+idejobJobs+"  config_idejobJobs:"+ide_job_jobs_limit+"  current_totalJobs:"+totalJobs+"  config_totalJobs:"+total_jobs_limit_ide_job);
            return;
        }

        float idejobRate = Float.parseFloat(idejobJobs)/Float.parseFloat(totalJobs);
        idejobRate = idejobRate*100;
        float ide_job_rate = Float.parseFloat(PropertiesUtil.get("ide_job_rate").trim());
        String alarm_limit_time = PropertiesUtil.get("alarm_limit_time").trim();
        if(idejobRate>ide_job_rate) {
            //告警的手机号
            String alarm_list = PropertiesUtil.get("alarm_phone_list").trim();
            String alarm_title = "ide_job过高";
            String rate = UUIDByDateUtils.twoPointNumbers(idejobRate+"");
            String alarm_content = "ide_job的任务数过多,共有:" + idejobJobs + " 个,总任务数有:" + totalJobs + " 个,所占比例为:" + rate + "%";

            //判断在告警记录表(job_source_alarm)中是否有同类型的job告警过,如果alarm_time到当前时间超过了配置中限制时间alarm_limit_time则告警,
            // 否则不同时满足比例大于指定比例,间隔时间不大于指定时间则不告警
            //表jobs_source_alarm告警类型;1表示buffalo,2表示gateone,3表示ide_online,4表示ide_job
            String sql = "SELECT j.id,j.alarm_time FROM jobs_source_alarm j WHERE j.alarm_type=4 ORDER BY id DESC LIMIT 1";
            Connection connection = null;
            ResultSet rs = null;
            try {
                connection = MySQLUtils.getConnection();
                rs = MySQLUtils.query(connection,sql);
                rs.next();
                int rows =   rs.getRow();
                //大于0说明jobs_source_alarm中已经告警过该类型的jobs,则根据alarm_time与当前时间判断是否超过了配置中设置的间隔时间alarm_limit_time,超过则再一次告警
                //超过后告警成功则把新的告警记录保存下来,没超过就不用管了
                String addSql = "INSERT INTO jobs_source_alarm (alarm_type,alarm_time,alarm_limit_time,total_jobs,alarm_jobs,alarm_limit_rate) VALUES(4,'" + currentTime + "','" + alarm_limit_time + "'," + totalJobs + "," + idejobJobs + "," + ide_job_rate + ")";
                if (rows > 0) {
                    String last_alarm_time = rs.getString("alarm_time");
                    boolean idejobFlag = jdugeJobTimeOut(currentTime, last_alarm_time, Integer.parseInt(alarm_limit_time.trim()));
                    if (idejobFlag) {
                        LOGGER.info("ide_job在jobs_source_alarm中有该类型告警记录,本次告警距离上次告警超过了指定间隔时间,将告警:" + alarm_content);
                        String flag = SendMessagesUtils.sendMessagesToPhone(alarm_list,alarm_title,alarm_content);
                        if (flag.equals("1")) {
                            LOGGER.info("ide_job类型再次告警发送短信成功...");
                            MySQLUtils.executeUpdate(connection, addSql);
                        } else {
                            LOGGER.error("ide_job告警发送短信失败!!!");
                        }
                    }
                } else {//该类型的job还没有告警过,直接告警,并保存告警记录
                    String flag = SendMessagesUtils.sendMessagesToPhone(alarm_list,alarm_title,alarm_content);
                    if (flag.equals("1")) {
                        LOGGER.info("ide_job该类型首次告警发送短信成功...");
                        MySQLUtils.executeUpdate(connection, addSql);
                    } else {
                        LOGGER.error("ide_job告警发送短信失败!!!");
                    }
                }
                MySQLUtils.returnConnection(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            LOGGER.info("ide_job本次统计比例没有超过指定的比例...");
        }
    }


    public static String countJobs(String sql,Connection connection) throws  Exception{
        ResultSet rs = MySQLUtils.query(connection,sql);
        rs.next();
        int rows = rs.getRow();
        String sumnums = "0";
        if(rows>0){
            sumnums = rs.getString(1);
        }else{
            LOGGER.info("sql没有查到数据:"+sql);
        }
        return  sumnums;
    }


    /**
     * 判断时间是否超时
     * @param current_time
     * @param last_alarm_time
     * @param limit_time
     * @return
     */
    public static  boolean  jdugeJobTimeOut(String current_time,String last_alarm_time,int limit_time){

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        boolean flag = false;//默认开始没有超时
        try {
            Date new_date = sdf.parse(current_time.trim());
            long new_time = new_date.getTime();

            Date old_date = sdf.parse(last_alarm_time.trim());
            long old_time = old_date.getTime();

            long exe_time = (new_time-old_time)/1000;
            if(exe_time>limit_time){//超时
                flag = true;
            }
        } catch (ParseException e) {
            e.printStackTrace();
            throw new RuntimeException("判断job来源比例时间是否超过上次告警时间...异常:"+e.getMessage());
        }
        return flag;
    }
}
